package com.xlh.service.system.impl;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.xlh.dao.system.PermissionMapper;
import com.xlh.dao.system.SystemConfigMapper;
import com.xlh.dao.system.ext.PermissionMapperExt;
import com.xlh.dao.system.ext.SystemConfigMapperExt;
import com.xlh.dto.system.IconDTO;
import com.xlh.dto.system.ValueDTO;
import com.xlh.enums.LocalResourcesEnum;
import com.xlh.enums.PermissionEnum;
import com.xlh.enums.SystemConfigEnum;
import com.xlh.exception.common.GlobalException;
import com.xlh.pojo.system.Permission;
import com.xlh.pojo.system.PermissionExample;
import com.xlh.pojo.system.SystemConfig;
import com.xlh.pojo.system.SystemConfigExample;
import com.xlh.service.system.SystemConfigService;
import com.xlh.util.BeanUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 系统配置
 * <p>
 * Created by lx on 2019/1/28.
 */
@Service
public class SystemConfigServiceImpl implements SystemConfigService {

    @Autowired
    private SystemConfigMapper systemConfigMapper;

    @Autowired
    private SystemConfigMapperExt systemConfigMapperExt;

    @Autowired
    private PermissionMapper permissionMapper;

    @Autowired
    private PermissionMapperExt permissionMapperExt;

    @Override
    public List<SystemConfig> listConfig(List<Integer> configIds, SystemConfigEnum configEnum) {
        SystemConfigExample example = new SystemConfigExample();
        SystemConfigExample.Criteria criterion = example.createCriteria();
        if (CollectionUtils.isNotEmpty(configIds)) {
            criterion.andIdIn(configIds);
        }
        if (configEnum != null) {
            criterion.andKeyWordEqualTo(configEnum.getKey());
        }
        return systemConfigMapper.selectByExample(example);
    }

    @Override
    public List<SystemConfig> listConfigByKeys(List<String> keys) {
        SystemConfigExample example = new SystemConfigExample();
        example.createCriteria().andKeyWordIn(keys);
        return systemConfigMapper.selectByExample(example);
    }

    @Override
    public Map<String, List<ValueDTO>> listConfigByKey(List<String> keys) {

        // 验证并过滤参数
        if (CollectionUtils.isEmpty(keys)) return null;
        keys = SystemConfigEnum.filterKeys(keys);

        Map<String, List<ValueDTO>> result = Maps.newHashMap();

        // 查询数据库配置文件表，返回Map<String,List<String>> 结果集
        List<SystemConfig> systemConfigs = listConfigByKeys(keys);
        systemConfigs.forEach(systemConfig -> {
            ValueDTO valueDTO = new ValueDTO();
            valueDTO.setId(systemConfig.getId());
            valueDTO.setKeyValue(systemConfig.getKeyValue());
            valueDTO.setKeyWord(systemConfig.getKeyWord());
            List<ValueDTO> data = result.get(systemConfig.getKeyWord());
            if (data == null) {
                data = Lists.newArrayList();
            }
            data.add(valueDTO);
            result.put(systemConfig.getKeyWord(), data);
        });

        return result;
    }

    @Override
    public <T extends IconDTO> List<T> convertIcon(List<T> data, LocalResourcesEnum resourcesEnum) {

        if (CollectionUtils.isEmpty(data)) return data;

        List<Integer> iconList = data.stream().map(t -> t.getIcon()).collect(Collectors.toList());

        List<SystemConfig> systemConfigs = listConfig(iconList, null);
        Map<Integer, SystemConfig> map = BeanUtil.mapByKey("id", systemConfigs);
        data.forEach(t -> {
            if (MapUtils.isNotEmpty(map) && map.get(t.getIcon()) != null) {
                t.setIconPath(resourcesEnum.getMappingUrl(map.get(t.getIcon()).getKeyValue()));
            }
        });
        return data;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateSystemConfig(SystemConfigEnum systemConfigEnum, String value) {

        SystemConfig systemConfig = convertSystemConfig(systemConfigEnum.getKey(), value);

        List<SystemConfig> list = listConfigByKeys(Lists.newArrayList(systemConfigEnum.getKey()));
        if (CollectionUtils.isEmpty(list)) {
            insertSystemConfig(systemConfig);
            return;
        }
        systemConfig.setId(list.stream().findFirst().get().getId());
        systemConfigMapper.updateByPrimaryKeySelective(systemConfig);

    }

    @Override
    public List<Permission> queryPermission(List<Long> objs, PermissionEnum permissionEnum) {
        if (CollectionUtils.isEmpty(objs)) return Lists.newArrayList();
        PermissionExample example = new PermissionExample();
        example.createCriteria().andObjIdIn(objs).andCodeEqualTo(permissionEnum.getCode());
        return permissionMapper.selectByExample(example);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void insertOrUpdatePermission(List<Long> userIds, List<Integer> status, PermissionEnum permissionEnum) {
        // 检查课程体系参数
        if (CollectionUtils.isNotEmpty(status)) {
            checkCourseDirection(status);
        }

        // 获取数据库用户与课程体系权限数据 并 删除
        List<Permission> permissionList = queryPermission(userIds, permissionEnum);
        deletePermission(permissionList.stream().map(Permission::getId).collect(Collectors.toList()));

        // 插入数据库
        if (CollectionUtils.isNotEmpty(status)) {
            permissionMapperExt.insertBatchPermission(convert(userIds, status, permissionEnum));
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void insertOrUpdatePermission(List<Permission> permissions) {
        List<Permission> insertData = permissions.stream()
                .filter(permission -> permission.getId() == null).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(insertData)) {
            permissionMapperExt.insertBatchPermission(insertData);
        }
        List<Permission> updateData = permissions.stream()
                .filter(permission -> permission.getId() != null).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(updateData)) {
            permissionMapperExt.updateBatchPermission(updateData);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deletePermission(List<Long> ids) {
        if (CollectionUtils.isEmpty(ids)) return;
        PermissionExample example = new PermissionExample();
        example.createCriteria().andIdIn(ids);
        permissionMapper.deleteByExample(example);
    }

    @Override
    public void deletePermissionByObjIds(List<Long> objIds, PermissionEnum permissionEnum) {
        if (CollectionUtils.isEmpty(objIds)) return;
        PermissionExample example = new PermissionExample();
        example.createCriteria().andObjIdIn(objIds).andCodeEqualTo(permissionEnum.getCode());
        permissionMapper.deleteByExample(example);
    }

    @Override
    public void insertSystemConfig(SystemConfig config) {
        systemConfigMapper.insertSelective(config);
    }

    @Override
    public void cleanDB() {
        systemConfigMapperExt.cleanDB();
    }

    private void checkCourseDirection(List<Integer> status) {
        List<SystemConfig> configs = listConfigByKeys(
                Lists.newArrayList(SystemConfigEnum.SCHOOL_TYPE.getKey()));
        List<Integer> configIds = configs.stream().map(SystemConfig::getId).collect(Collectors.toList());
        if (status.stream().filter(id -> !configIds.contains(id)).count() > 0) {
            throw new GlobalException("学校类型不存在");
        }
    }

    private List<Permission> convert(List<Long> userIds, List<Integer> status, PermissionEnum permissionEnum) {
        List<Permission> list = Lists.newArrayList();
        userIds.forEach(userId -> {
            status.forEach(id -> {
                Permission permission = new Permission();
                permission.setCode(permissionEnum.getCode());
                permission.setStatus(id);
                permission.setObjId(userId);
                list.add(permission);
            });
        });

        return list;
    }

    private SystemConfig convertSystemConfig(String key, String value) {
        SystemConfig systemConfig = new SystemConfig();
        systemConfig.setKeyWord(key);
        systemConfig.setKeyValue(value);
        return systemConfig;
    }

}
